#include "csocketcommunication.h"
#include <assert.h>
#include <QString>
#include <QTcpSocket>
#include <QHostAddress>
#include "CNetworkFactory.h"
#include "inetworking.h"

extern CSocketCommunication socketCom;

CSocketCommunication::CSocketCommunication()
{
    pNetWorking = NULL;
    param = NULL;
    nextBlockSize = 0;

    connect(&tcpSocket, SIGNAL(connected() ), this, SLOT(hasConnected()) );
    connect(&tcpSocket, SIGNAL(disconnected() ), this, SLOT(connectionClosedByServer()) );
    connect(&tcpSocket, SIGNAL(readyRead() ), this, SLOT(readyRead()) );
    connect(&tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)) , this, SLOT(error()) );
}

CSocketCommunication::~CSocketCommunication()
{
    if (param != NULL)
    {
        delete [] param;
    }
}

void CSocketCommunication::connectToServer(QString serverIP, unsigned short port)
{
    QHostAddress address(serverIP);

    tcpSocket.connectToHost(address, port);
}

//void CSocketCommunication::setupNetworkingClass(INetWorking* networkingclass)
//{
//    pNetWorking = networkingclass;
//}

void CSocketCommunication::sendRequest(QString serverIP, unsigned short port, int command, void *para, int size)
{
    assert(para != NULL);
    assert(size > 0);

    this->connectToServer(serverIP, port);

    this->command = command;

    if (this->param != NULL)
    {
        delete [] this->param;
    }

    this->param = new char [size];

    memcpy(param , para, size);
}

void CSocketCommunication::stopRequest()
{
    this->closeConnection();
}

void CSocketCommunication::closeConnection()
{
    tcpSocket.close();
}

void CSocketCommunication::readyRead()
{
    pNetWorking->recieveData(tcpSocket.bytesAvailable(), &tcpSocket);

    emit canRead();
}

void CSocketCommunication::connectionClosedByServer()
{   
    // emit the closeByServer signal, indicating that the communication was closed by server
    emit closeByServer();

    this->closeConnection();
}

void CSocketCommunication::error()
{
    emit socketError();

    this->closeConnection();
}

QMap<QString, QString> CSocketCommunication::getResult()
{
    return pNetWorking->getResult();
}

QString CSocketCommunication::getResult(QString name)
{
    return pNetWorking->getResult(name);
}

void CSocketCommunication::hasConnected()
{
    qDebug() << "connect has been established, is sending request\n";

    pNetWorking = CNetworkFactory::getNetworkClass(this->command);

    QByteArray block;

    pNetWorking->setData(this->param, &block);

    tcpSocket.write(block);
}

